﻿using System;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Ink;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using System.Collections.Generic;
using System.Xml.Linq;
using System.Xml.Serialization;
using System.IO;
using System.Text;
using System.Xml;
using System.Runtime.Serialization;

namespace Nav
{
    [DataContract]
    public class SearchParameter
    {
        [XmlAttribute()]
        [DataMember]
        public string Name
        {
            get;
            set;
        }

        [XmlAttribute()]
        [DataMember]
        public string Value
        {
            get;
            set;
        }
    }

    [DataContract]
    public class Node
    {
        public event Action<Node>                   Command;

        [XmlAttribute()]
        [DataMember]
        public string Name
        {
            get;
            set;
        }

        [XmlAttribute()]
        [DataMember]
        public string Category
        {
            get;
            set;
        }

        [XmlAttribute()]
        [DataMember]
        public string Data
        {
            get;
            set;
        }

        [XmlAttribute()]
        [DataMember]
        public string Icon
        {
            get;
            set;
        }

        [DataMember]
        public List<SearchParameter> SearchParameters
        {
            get;
            set;
        }

        [DataMember]
        public List<Node> Nodes
        {
            get;
            set;
        }

        public Visibility NextLevelVisibility
        {
            get
            {
                return Nodes.Count > 0 ? Visibility.Visible : Visibility.Collapsed;
            }
        }

        /// 
        /// <summary>
        /// Executes assigned action if any</summary>
        /// 
        public bool ExecuteCommand()
        {
            bool                                    executed;

            executed = false;

            if (Command != null)
            {
                 Command(this);
                 executed = true;
            }
            return executed;
        }

        #region De/Serialization

        /// 
        /// <summary>
        /// Serializes node to byte array</summary>
        /// 
        public static byte[] BinarySerialize(Node n)
        {
            DataContractSerializer                      dc;
            MemoryStream                                stream;


            stream = new MemoryStream();
            dc = new DataContractSerializer(typeof(Node)); 

            // Serialize from an object to a stream
            dc.WriteObject(stream, n); 
            
            return stream.GetBuffer();
        }

        /// 
        /// <summary>
        /// Deserializes node from stream with binary data</summary>
        /// 
        public static Node BinaryDeserialize(Stream s)
        {
            DataContractSerializer                      dc;

            dc = new DataContractSerializer(typeof(Node)); 

            return (Node) dc.ReadObject(s);
        }

        /// 
        /// <summary>
        /// Deserializes node from stream with xml data</summary>
        /// 
        public static Node Deserialize(Stream s)
        {
            XmlSerializer                   xs;

            xs = new XmlSerializer(typeof(Node));

            return (Node) xs.Deserialize(s);
        }

        #endregion
    }
}
